# coding= utf-8

import requests
import json
import sys
import codecs
import warnings
import pymongo
from collections import deque

sys.stdout = codecs.getwriter('utf-8')(sys.stdout.detach())
warnings.filterwarnings("ignore")


class Keepa:
    def __init__(self):
        self.lr = {}
        self.api_prefix = 'https://api.keepa.com/category'
        self.api_current = ''
        # self.api_key1 = '2dk1l3e09o7hvjhcqg67lnrspsmmp3at0jikcsu9e8f257kstasjvev8thh0g1uv'
        # self.new_token = '6nokjd8r4ev0aq7ic6sktl1a1nc2a7l3eqr6k91l85qhtdkm1g9fvhmrbq8uapki'  # 新账户token
        self.api_key = 'cqqkcu49mds3vp4u4v8om3qtmmfl4l63038r1httn5tun9tu155u39k4kpkbsj2k'  # 付费token
        self.asset_url = 'https://m.media-amazon.com/images/I/'
        self.token_url = 'https://api.keepa.com/token'
        self.config = []
        self.my_list = []
        self.all_categories = []

        # 连接MongoDB
        # current_datetime = datetime.datetime.now()
        # current_year = current_datetime.year
        self.myclient = pymongo.MongoClient("mongodb://localhost:27017/")
        mydb = self.myclient["xp_analyse"]
        self.my_category = mydb["wt_category"]
        self.my_config = mydb["wt_config"]

    def get_category(self):
        self.config = self.my_config.find_one()

        # 创建索引
        indexlist = self.my_category.index_information()
        if not indexlist:
            self.my_category.create_index("catId")
            self.my_category.create_index("name")
            self.my_category.create_index("parent_id")

        domain = translate_locale(self.config['country'])
        self.send_keepa(int(domain), '0', False)

        # 循环一级分类插入子分类
        cates = self.my_category.find({'parent_id': 0})
        for c in cates:
            self.send_keepa(domain, c['children_str'], True)

        self.myclient.close()
        exit()

    def send_keepa(self, domain, pid, is_all=True):
        print('获取分类ID：' + pid)
        print('is_all：' + str(is_all))
        pid_arr = pid.split(',')
        if len(pid_arr) > 10:
            pid_circle = [pid_arr[i:i + 10] for i in range(0, len(pid_arr), 10)]
            for item in pid_circle:
                self.send_keepa(domain, ','.join([str(x) for x in item]), is_all)
        else:
            url = self.api_prefix
            params = {
                'key': self.api_key,
                'domain': domain,
                'parents': 1,
                'category': pid,
            }
            # print(params)
            # exit()
            response = requests.get(url=url, params=params)

            # 判断状态码
            status_code = response.status_code
            if not int(status_code) == 200:
                print('状态码：' + str(status_code) + '请求失败，等待下次重试！')
                self.myclient.close()
                exit()
            res = json.loads(response.text)

            # 判断请求是否成功
            if "error" in res:
                print(res['error']['message'])

            if "categories" in res:
                for index in res['categories']:
                    i = res['categories'][index]

                    # 仅获取有效分类
                    if i['isBrowseNode']:
                        # 获取子分类以及子分类个数
                        if 'children' in i and not i['children'] == None:
                            children_str = ','.join([str(x) for x in i['children']])
                            children_num = len(i['children'])
                        else:
                            children_str = ''
                            children_num = 0

                        value = dict([
                            ['catId', i['catId']],
                            ['domainId', i['domainId']],
                            ['name', i['name']],
                            ['isBrowseNode', i['isBrowseNode']],
                            ['parent_id', i['parent']],
                            ['month', self.config['month']],
                            ['children_str', children_str],
                            ['children_num', children_num],
                        ])

                        self.my_category.insert(value)
                        print('插入数据：' + str(value))

                        # 递归获取子分类
                        if children_num > 0 and is_all:
                            print('获取子分类')
                            original_list = i['children']
                            chunk_size = 10
                            split_lists = [original_list[i:i + chunk_size] for i in
                                           range(0, len(original_list), chunk_size)]
                            for item in split_lists:
                                self.send_keepa(domain, ','.join([str(x) for x in item]), is_all)
                    else:
                        print('非可用分类-isBrowseNode：' + str(i['isBrowseNode']))
            else:
                print('返回结果无分类！')

    # 定义请求接口api的方法
    def getCategoryInfos(self, categoryIds):
        url = "https://api.keepa.com/category?key=" + self.api_key + "&domain=" + str(translate_locale(self.config['country'])) + "&category=" + str(categoryIds) + "&parents=1"
        response = requests.get(url)
        getSubCategoryIds = []
        if response.status_code == 200:
            data = response.json()
            for item in data['categories']:
                ret = {}
                if data['categories'][item]['isBrowseNode']:
                    ret['parent'] = data['categories'][item]['parent']
                    ret['domainId'] = data['categories'][item]['domainId']
                    ret['catId'] = data['categories'][item]['catId']
                    ret['name'] = data['categories'][item]['name']
                    ret['children'] = data['categories'][item]['children']
                    getSubCategoryIds.append(ret)
        return getSubCategoryIds

    # 循环请求接口得到给定父分类的子分类，由于接口限制一次只能传递10个分类id获取对应的子分类信息数据
    def recursionSubCategoriesDeque(self, parent_ids):
        # 定义一个双向队列，每次从队列头部取10个id去请求接口，接口返回的子分类信息id统统从队列尾部插入到该双向队列中
        category_id_list = deque(parent_ids)
        while category_id_list:
            batch_ids = [category_id_list.popleft() for _ in range(min(10, len(category_id_list)))]
            parent_ids_str = ','.join(str(i) for i in batch_ids)
            print('当前category_id_list长度:', len(category_id_list))

            # 返回给定10个ids的所有分类信息retData，
            retData = self.getCategoryInfos(parent_ids_str)
            for i in retData:
                if 'children' in i and not i['children'] == None:
                    category_id_list.extend(i['children'])
                    children_str = ','.join([str(x) for x in i['children']])
                    children_num = len(i['children'])
                else:
                    children_str = ''
                    children_num = 0
                value = dict([
                    ['catId', i['catId']],
                    ['domainId', i['domainId']],
                    ['name', i['name']],
                    ['parent_id', i['parent']],
                    ['month', self.config['month']],
                    ['children_str', children_str],
                    ['children_num', children_num],
                ])
                print(value)
                self.all_categories.append(value)

    def get_category_new(self):
        self.config = self.my_config.find_one()
        exist = self.my_category.find_one({"month": self.config['month'], "domainId": translate_locale(self.config['country'])})
        if exist:
            print(self.config['month'] + '-数据已生成/或正在生成中，请勿重复请求！')
            self.myclient.close()
            exit()

        # 调用函数并传递初始分类 ID 列表
        self.recursionSubCategoriesDeque([0])

        # 插入数据库
        re = self.my_category.insert_many(self.all_categories)
        print(re.acknowledged)


def translate_domain(domain):
    dis = {1: 'com', 2: 'co.uk', 3: 'de', 4: 'fr', 5: 'co.jp', 6: 'ca', 8: 'it', 9: 'es', 10: 'in', 11: 'com.mx'}
    return dis.get(domain)


def translate_locale(domain):
    dis = {'com': 1, 'co.uk': 2, 'de': 3, 'fr': 4, 'co.jp': 5, 'ca': 6, 'it': 8, 'es': 9, 'in': 10, 'com.mx': 11}
    return dis.get(domain)


keepa = Keepa()
keepa.get_category_new()
